www.gusucode.com > LTE基带收发仿真系统matlab源码程序 > LTE baseband simulation/de_precoding.m

    function recLayerSymb = de_precoding(recPrecodedSymb,HfreqCell,iUE,SNRdB)
% 功能:根据估计的信道矩阵和发端预编码向量,计算等效的信道,并是用MMSE、ZF算法估计发送信号 
% 输入:
%     recPrecodedSymb:接收的预编码符号
%           HfreqCell:信道的频域矩阵
%                 iUE:第i个用户
%               SNRdB:信噪比,dB表示
% 输出:
%        recLayerSymb:解预编码的输出,得到每一层的符号
%  
%  Author:		程式小组(徐萌 张妙 张晓庆)
%  Date:		2010-07-11
%  ==============================================


global LTE_par
nTx = LTE_par.BS_par.nAnt;
nRx = LTE_par.UE_par.nAnt;
CFI = LTE_par.CFI;
scPerRB = LTE_par.scPerRB;
nOfdmSymb = LTE_par.nOfdmSymb;
nRB = LTE_par.UE_par.nRB(iUE);
M_0_SYMB = LTE_par.UE_par.M_0_SYMB(iUE);
cellID = LTE_par.BS_par.cellID;         % 小区ID号
iSubFrame = LTE_par.iSubFrame;          % 当前子帧号 取值为0~9
ns = iSubFrame*2;                       % 时隙号
nLayer = LTE_par.UE_par.nLayer(iUE);    % 层数
detecAlg = LTE_par.UE_par.detecAlg;            % MIMO检测算法 'MMSE' 或 'ZF'
% 预处理模式
% - 'singleAnt':单天线
% - 'spatialMultiplexing':空间复用
% - 'tranmitDiversity': 传输分集
preProcess = LTE_par.UE_par.preProcess;

%  ==============  测试使用 =================================
% nTx = 1;
% CFI = 2;
% scPerRB = 12;
% nOfdmSymb = 14;
% nRB = 5;
% M_0_SYMB = 660;
% cellID = 0;
% ns = 2;
% ===========================================================

nSubCarr = nRB*scPerRB; % 第iUE个用户占用的子载波数
% 导频占用位置
pilotLocation = find_pilot(cellID,nTx,scPerRB,nOfdmSymb,nRB,ns);

if strcmp(preProcess,'singleAnt')
    
    % 单天线情形下的频域均衡
    % 经过时域或频域信道时,接收端进行频域均衡
    recLayerSymb = zeros(nLayer,M_0_SYMB);
    iSymb = 1;
    for iOfdm = CFI+1:nOfdmSymb
        for iCarr = 1:nSubCarr
            if pilotLocation(iCarr,iOfdm) == 0
                r = zeros(nRx,1); % 载波上接收符号
                H = HfreqCell{iCarr}; % 载波上的信道矩阵
                for iRx = 1:nRx
                    r(iRx) = recPrecodedSymb{iRx}(iCarr,iOfdm);
                end
                
                if strcmp(detecAlg,'MMSE')
                    xEst = mmse_detect(r,H,SNRdB); % MMSE检测
                elseif strcmp(detecAlg,'ZF')
                    xEst = zf_detect(r,H); % ZF检测
                end

                recLayerSymb(:,iSymb) = xEst;
                iSymb = iSymb+1;
            end
        end
    end

    
elseif strcmp(preProcess,'spatialMultiplexing')
    
    recLayerSymb = zeros(nLayer,M_0_SYMB);
    %载入预编码码本 W_SM_2Tx(2天线码本)和W_SM_4Tx(4天线码本)
    load CodeBook
    
    % 第iUE个用户预编码序号
    PMI = LTE_par.UE_par.PMI(iUE);
    
    % 2天线端口配置,空间复用的码本大小:2*2*8  W_SM_2Tx
    % 4天线端口配置,空间复用的码本大小:4*4*64 W_SM_4Tx
    % 码本使用举例 W_SM_4Tx(:,1:3,33) 第一维表示天线数 第二维表示层数 第三维表示属于层3的第2个码字
    PMI = PMI+1+(nLayer-1)*2^nTx;
    
    if nTx == 2
        iSymb = 1;
        for iOfdm = CFI+1:nOfdmSymb
            for iCarr = 1:nSubCarr
                if pilotLocation(iCarr,iOfdm) == 0
                    % 载波上的信道矩阵
                    H = HfreqCell{iCarr};
                    % 实际信道矩阵乘以预编码,得到等效信道
                    W = W_SM_2Tx(:,1:nLayer,PMI);
                    Heq = H*W;
                    % 载波上接收符号
                    r = zeros(nRx,1);
                    
                    for iRx = 1:nRx
                        r(iRx) = recPrecodedSymb{iRx}(iCarr,iOfdm);
                    end
                    
                    if strcmp(detecAlg,'MMSE')
                        xEst = mmse_detect(r,Heq,SNRdB); % MMSE检测
                    elseif strcmp(detecAlg,'ZF')
                        xEst = zf_detect(r,H); % ZF检测
                    end
                    
                    recLayerSymb(:,iSymb) = xEst;
                    iSymb = iSymb+1;
                end
            end
        end
        
    elseif nTx == 4
        iSymb = 1;
        for iOfdm = CFI+1:nOfdmSymb
            for iCarr = 1:nSubCarr
                if pilotLocation(iCarr,iOfdm) == 0
                    % 载波上的信道矩阵
                    H = HfreqCell{iCarr};
                    % 实际信道矩阵乘以预编码,得到等效信道
                    W = W_SM_4Tx(:,1:nLayer,PMI);
                    Heq = H*W;
                    % 载波上接收符号
                    r = zeros(nRx,1);
                    
                    for iRx = 1:nRx
                        r(iRx) = recPrecodedSymb{iRx}(iCarr,iOfdm);
                    end
                    
                    if strcmp(detecAlg,'MMSE')
                        xEst = mmse_detect(r,Heq,SNRdB); % MMSE检测
                    elseif strcmp(detecAlg,'ZF')
                        xEst = zf_detect(r,H); % ZF检测
                    end
                    
                    recLayerSymb(:,iSymb) = xEst;
                    iSymb = iSymb+1;
                end
            end
        end
        
    end
    
elseif strcmp(preProcess,'tranmitDiversity')
    
    if nTx == 2
        
        iSymb = 1;
        recLayerSymb = zeros(nLayer,M_0_SYMB/2);
        
        for iOfdm = CFI+1:nOfdmSymb

            availableDataCarr = find(pilotLocation(:,iOfdm)==0); % 得到第iOfdm个OFDM符号上数据可用载波
            len = length(availableDataCarr);
            groupSize = 2; % 一组SFBC 编码占用的载波数
            for iGroup = 1:2:len
                tempPre = zeros(groupSize*nTx,1); % 存放相邻两个载波上的取MIMO估计符号
                
                for itd = 1:groupSize
                    % 提取载波上符号,信道
                    r = zeros(nRx,1);
                    for iRx = 1:nRx
                        r(iRx) = recPrecodedSymb{iRx}(availableDataCarr(iGroup+itd-1),iOfdm);
                    end
                    H = HfreqCell{availableDataCarr(iGroup+itd-1)};
                    
                    if strcmp(detecAlg,'MMSE')
                        xEst = mmse_detect(r,H,SNRdB); % MMSE检测
                    elseif strcmp(detecAlg,'ZF')
                        xEst = zf_detect(r,H); % ZF检测
                    end
                    
                    tempPre((itd-1)*nTx+1:itd*nTx) = xEst;
                end
                U = sqrt(2)*[1 0 0 1;0 -1 1 0;1 0 0 -1;0 1 1 0]; % ZF MMSE下去预编码矩阵
                tempPre = U*tempPre;
                tempPre = tempPre/2;
                
                iLayerSymb = [real(tempPre(1))+1i*imag(tempPre(3));real(tempPre(2))+1i*imag(tempPre(4))];
                recLayerSymb(:,iSymb) = iLayerSymb;
                iSymb = iSymb+1;
                
            end
            
        end
        
    elseif nTx == 4
        
        if mod(M_0_SYMB,4) ~= 0
            recLayerSymb = zeros(nLayer,(M_0_SYMB+2)/4);
        else
            recLayerSymb = zeros(nLayer,M_0_SYMB/4);
        end
        
        iSymb = 1;
        
        for iOfdm = CFI+1:nOfdmSymb
            
            availableDataCarr = find(pilotLocation(:,iOfdm)==0); % 得到第iOfdm个OFDM符号上数据可用载波
            len = length(availableDataCarr);
            groupSize = 4; % 一组SFBC 编码占用的载波数
            for iGroup = 1:4:len
                tempPre = zeros(groupSize*nTx,1); % 存放相邻两个载波上的取MIMO估计符号
                
                for itd = 1:groupSize
                    % 提取载波上符号,信道
                    r = zeros(nRx,1);
                    for iRx = 1:nRx
                        r(iRx) = recPrecodedSymb{iRx}(availableDataCarr(iGroup+itd-1),iOfdm);
                    end
                    xEst = zeros(1,groupSize);
                    if itd<=2;
                        H = HfreqCell{availableDataCarr(iGroup+itd-1)}(:,[1 3]);
                        if strcmp(detecAlg,'MMSE')
                            xEst([1 3]) = mmse_detect(r,H,SNRdB); % MMSE检测
                        elseif strcmp(detecAlg,'ZF')
                            xEst([1 3]) = zf_detect(r,H); % ZF检测
                        end
                    else
                        H = HfreqCell{availableDataCarr(iGroup+itd-1)}(:,[2 4]);
                        if strcmp(detecAlg,'MMSE')
                            xEst([2 4]) = mmse_detect(r,H,SNRdB); % MMSE检测
                        elseif strcmp(detecAlg,'ZF')
                            xEst([2 4]) = zf_detect(r,H); % ZF检测
                        end
                    end
                    
                    tempPre((itd-1)*nTx+1:itd*nTx) = xEst;
                    
                end
                
                U = sqrt(2)*[1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0;
                    0 0 -1 0 1 0 0 0 0 0 0 0 0 0 0 0;
                    0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1;
                    0 0 0 0 0 0 0 0 0 0 0 -1 0 1 0 0;
                    1 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 0;
                    0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0;
                    0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 -1;
                    0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0];% ZF MMSE下去预编码矩阵
                
                tempDepre = U*tempPre;
                tempDepre = tempDepre/2;
                
                iLayerSymb = real(tempDepre(1:4))+1i*imag(tempDepre(5:8));
                
                recLayerSymb(:,iSymb) = iLayerSymb;
                iSymb = iSymb+1;
                
            end % end for SFBC解码组
            
        end % end for ofdm符号循环
        
    end % end if 发端天线数判断
    
end % end if 预处理模式判断